package model

import (
	"bytes"
	"errors"
	"github.com/jmoiron/sqlx"
	"strings"
	"time"
)

// 观测记录信息
type Tpsmeasurements struct {
	ID                int       `db:"ID"`                //观测记录标识ID
	Type              int16     `db:"Type"`              //监测类别
	TPSSetupID        int       `db:"TPSSetup_ID"`       //设站ID
	PointGroupID      int       `db:"PointGroup_ID"`     //观测点组
	PointID           int       `db:"Point_ID"`          //观测点ID
	ReflectorHeight   float64   `db:"ReflectorHeight"`   //棱镜高
	ReflectorConstant float64   `db:"ReflectorConstant"` //棱镜常数
	TurnNo            int       `db:"TurnNo"`            //测回
	Epoch             time.Time `db:"Epoch"`             //观测日期
	Description       string    `db:"Description"`       //备注
	HzAngleL          float64   `db:"HzAngleL"`          //水平度盘左
	VangleL           float64   `db:"VangleL"`           //竖直度盘左
	SlopeDistanceL    float64   `db:"SlopeDistanceL"`    //斜距左(距离是经过大气、仪器常数、棱镜常数、地球曲率等改正后的值)
	HzAngleR          float64   `db:"HzAngleR"`          //水平度盘右
	VangleR           float64   `db:"VangleR"`           //竖直度盘右
	SlopeDistanceR    float64   `db:"SlopeDistanceR"`    //斜距右
	EDMMode           int16     `db:"EDMMode"`           //EDM模式
	State             int16     `db:"State"`             //状态
	Zeroing           bool      `db:"Zeroing"`           //归零向标识
}

// 根据【观测记录标识ID】查询【观测记录信息】表中是否存在相关记录
func (d *Tpsmeasurements) Exist(ID int) (bool, error) {
	rows, err := amp.Queryx("SELECT COUNT(0) Count FROM tpsmeasurements WHERE ID=?", ID)
	if err != nil {
		return false, err
	}
	defer rows.Close()
	count := 0
	if rows.Next() {
		err = rows.Scan(&count)
		if err != nil {
			return false, err
		}
		return count > 0, nil
	}
	return false, nil
}

// 插入单条记录到【观测记录信息】表中
func (d *Tpsmeasurements) Insert() (int64, error) {
	result, err := amp.Exec("INSERT INTO tpsmeasurements(Type,TPSSetup_ID,PointGroup_ID,Point_ID,ReflectorHeight,ReflectorConstant,TurnNo,Epoch,Description,HzAngleL,VangleL,SlopeDistanceL,HzAngleR,VangleR,SlopeDistanceR,EDMMode,State,Zeroing) VALUES(?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)", d.Type, d.TPSSetupID, d.PointGroupID, d.PointID, d.ReflectorHeight, d.ReflectorConstant, d.TurnNo, d.Epoch, d.Description, d.HzAngleL, d.VangleL, d.SlopeDistanceL, d.HzAngleR, d.VangleR, d.SlopeDistanceR, d.EDMMode, d.State, d.Zeroing)
	if err != nil {
		return -1, err
	}
	return result.LastInsertId()
}

// 根据【观测记录标识ID】修改【观测记录信息】表的单条记录
func (d *Tpsmeasurements) Update() (bool, error) {
	result, err := amp.Exec("UPDATE tpsmeasurements SET Type=?, TPSSetup_ID=?, PointGroup_ID=?, Point_ID=?, ReflectorHeight=?, ReflectorConstant=?, TurnNo=?, Epoch=?, Description=?, HzAngleL=?, VangleL=?, SlopeDistanceL=?, HzAngleR=?, VangleR=?, SlopeDistanceR=?, EDMMode=?, State=?, Zeroing=? WHERE ID=?", d.Type, d.TPSSetupID, d.PointGroupID, d.PointID, d.ReflectorHeight, d.ReflectorConstant, d.TurnNo, d.Epoch, d.Description, d.HzAngleL, d.VangleL, d.SlopeDistanceL, d.HzAngleR, d.VangleR, d.SlopeDistanceR, d.EDMMode, d.State, d.Zeroing, d.ID)
	if err != nil {
		return false, err
	}
	affected, err := result.RowsAffected()
	if err != nil {
		return false, err
	}
	return affected > 0, nil
}

// 根据【观测记录标识ID】查询【观测记录信息】表中的单条记录
func (d *Tpsmeasurements) Get(ID int) (tpsmeasurements Tpsmeasurements, err error) {
	rows, err := amp.Queryx("SELECT ID, Type, TPSSetup_ID, PointGroup_ID, Point_ID, ReflectorHeight, ReflectorConstant, TurnNo, Epoch, Description, HzAngleL, VangleL, SlopeDistanceL, HzAngleR, VangleR, SlopeDistanceR, EDMMode, State, Zeroing FROM tpsmeasurements WHERE ID=?", ID)
	if err != nil {
		return tpsmeasurements, err
	}
	defer rows.Close()
	tpsmeasurementss, err := d._RowsToArray(rows)
	if err != nil {
		return tpsmeasurements, err
	}
	if len(tpsmeasurementss) <= 0 {
		return tpsmeasurements, err
	}
	return tpsmeasurementss[0], nil
}

// 根据【观测记录标识ID】数组查询【观测记录信息】表中的多条记录
func (d *Tpsmeasurements) GetIn(IDs []int) (tpsmeasurementss []Tpsmeasurements, err error) {
	if len(IDs) <= 0 {
		return tpsmeasurementss, errors.New("IDs is empty")
	}
	sqlStr := bytes.Buffer{}
	sqlStr.WriteString("SELECT ID, Type, TPSSetup_ID, PointGroup_ID, Point_ID, ReflectorHeight, ReflectorConstant, TurnNo, Epoch, Description, HzAngleL, VangleL, SlopeDistanceL, HzAngleR, VangleR, SlopeDistanceR, EDMMode, State, Zeroing FROM ")
	sqlStr.WriteString("tpsmeasurements")
	sqlStr.WriteString(" WHERE ID IN(")
	paramKeys := strings.Repeat("?,", len(IDs))
	sqlStr.WriteString(paramKeys[:len(paramKeys)-1])
	sqlStr.WriteString(")")
	var rows *sqlx.Rows
	vals := make([]interface{}, 0, len(IDs))
	for _, v := range IDs {
		vals = append(vals, v)
	}
	rows, err = amp.Queryx(sqlStr.String(), vals...)
	if err != nil {
		return tpsmeasurementss, err
	}
	defer rows.Close()
	return d._RowsToArray(rows)
}

// 查询【观测记录信息】表总记录数
func (d *Tpsmeasurements) GetRowCount() (count int, err error) {
	rows, err := amp.Queryx("SELECT COUNT(0) Count FROM tpsmeasurements")
	if err != nil {
		return -1, err
	}
	defer rows.Close()
	if rows.Next() {
		err = rows.Scan(&count)
		if err != nil {
			return -1, err
		}
		return count, nil
	}
	return -1, nil
}

// 分页查询【观测记录信息】表的记录
func (d *Tpsmeasurements) GetRowList(PageIndex, PageSize int) (tpsmeasurementss []Tpsmeasurements, err error) {
	rows, err := amp.Queryx("SELECT ID, Type, TPSSetup_ID, PointGroup_ID, Point_ID, ReflectorHeight, ReflectorConstant, TurnNo, Epoch, Description, HzAngleL, VangleL, SlopeDistanceL, HzAngleR, VangleR, SlopeDistanceR, EDMMode, State, Zeroing FROM tpsmeasurements LIMIT ?,?", (PageIndex-1)*PageSize, PageSize)
	if err != nil {
		return tpsmeasurementss, err
	}
	defer rows.Close()
	return d._RowsToArray(rows)
}

// 解析【观测记录信息】表记录
func (d *Tpsmeasurements) _RowsToArray(rows *sqlx.Rows) (models []Tpsmeasurements, err error) {
	for rows.Next() {
		mo := Tpsmeasurements{}
		err = rows.Scan(&mo.ID, &mo.Type, &mo.TPSSetupID, &mo.PointGroupID, &mo.PointID, &mo.ReflectorHeight, &mo.ReflectorConstant, &mo.TurnNo, &mo.Epoch, &mo.Description, &mo.HzAngleL, &mo.VangleL, &mo.SlopeDistanceL, &mo.HzAngleR, &mo.VangleR, &mo.SlopeDistanceR, &mo.EDMMode, &mo.State, &mo.Zeroing)
		if err != nil {
			return models, err
		}
		models = append(models, mo)
	}
	return models, err
}
